﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using MageWars.Support;
using MageWars.GameElements;

namespace MageWars
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        public const int NumIA = 40;
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);

            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {

            // TODO: Add your initialization logic here

            graphics.PreferredBackBufferWidth = 1180;
            graphics.PreferredBackBufferHeight = 700;
            graphics.IsFullScreen = false;
            graphics.ApplyChanges();

            LineBatch.Init(GraphicsDevice);

            this.TargetElapsedTime = TimeSpan.FromSeconds(1.0f / 45.0f);

            base.Initialize();

        }

        Mesh Graph;

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            LoadTextures();


            Graph = Mesh.GetMesh();


            var player = new PlayerMage();
            player.Position = new Vector3(15, 15, 0);


            // TODO: use this.Content to load your game content here
        }

        private void LoadTextures()
        {

            Textures.GameMap = Content.Load<Texture2D>("GameMap");
            Textures.CollisionMap = Content.Load<Texture2D>("CollisionMap");
            Textures.Team1Casting = Content.Load<Texture2D>("Team1Casting");
            Textures.Team1Spell = Content.Load<Texture2D>("Team1Spell");
            Textures.Team1Standing = Content.Load<Texture2D>("Team1Standing");
            Textures.Team1Walking1 = Content.Load<Texture2D>("Team1Walking1");
            Textures.Team1Walking2 = Content.Load<Texture2D>("Team1Walking2");

            Textures.Team2Casting = Content.Load<Texture2D>("Team2Casting");
            Textures.Team2Spell = Content.Load<Texture2D>("Team2Spell");
            Textures.Team2Standing = Content.Load<Texture2D>("Team2Standing");
            Textures.Team2Walking1 = Content.Load<Texture2D>("Team2Walking1");
            Textures.Team2Walking2 = Content.Load<Texture2D>("Team2Walking2");


            Textures.Black = Content.Load<Texture2D>("Black");
            Textures.Red = Content.Load<Texture2D>("Red");
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            foreach (var s in Projectile.Projectiles)
            {
                s.UpdatePosition();
            }
            foreach (var m in Mage.Mages)
            {
                m.VerifyAttackHit();
                m.UpdatePosition();
            }

            int nBlue = (from c in Mage.Mages where c.Group == Team.TeamBlue select c).Count();
            int nOrange = (from c in Mage.Mages where c.Group == Team.TeamOrange select c).Count();

            if (!(from c in Mage.Mages where c.GetType() == typeof(PlayerMage) select c).Any())
            {
                var player = new PlayerMage();
                player.Position = new Vector3(15, 15, 0);
            }

            while (nBlue < 4)
            {
                //new AiMage(new Vector3(15, 305, 0), Team.TeamBlue);
                new AiMage(new Vector3((nBlue * 60 + 15), 305, 0), Team.TeamBlue);
                nBlue++;
            }

            while (nOrange < 4)
            {
                //new AiMage(new Vector3(605, 305, 0), Team.TeamOrange);
                new AiMage(new Vector3((nOrange * 60 + 605), 305, 0), Team.TeamOrange);
                nOrange++;
            }

            base.Update(gameTime);
        }

        public static bool ShowMesh;
        protected override void Draw(GameTime gameTime)
        {

            GraphicsDevice.Clear(Color.Black);

            // spriteBatch.Begin();

            spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend);

            spriteBatch.Draw(Textures.GameMap, new Vector2(0, 0), Color.White);

            if (ShowMesh)
            {
                foreach (var r in Mesh.GetMesh().RectNodes.Keys)
                {
                    DrawRectangle(r);
                }

                foreach (var n in Graph.Nodes)
                {
                    spriteBatch.Draw(Textures.Red, new Rectangle((int)n.Position.X, (int)n.Position.Y, 3, 3), Color.Red);
                }
            }

            foreach (var n in Graph.Nodes)
            {

                foreach (var g in n.Nodes)
                {
                    spriteBatch.DrawLine(Color.Yellow, n.Position, g.Key.Position);
                }
            }

            foreach (var m in Mage.Mages)
            {
                DrawMovable(m);
                //DrawRectangle(m.BoundingBox);
                if (ShowMesh)
                {
                    spriteBatch.Draw(Textures.Red, new Rectangle((int)m.Position.X, (int)m.Position.Y, 3, 3), Color.Red);
                    var sm = m.GetSM();
                    if (sm != null)
                    {
                        var caminos = sm.CurrentState.GetCamino();
                        for (int j = 0; j < caminos.Length - 1; j++)
                        {
                            spriteBatch.DrawLine(Color.Yellow, caminos[j].Position, caminos[j + 1].Position);
                        }
                    }
                }
            }

            foreach (var s in Projectile.Projectiles)
            {
                DrawMovable(s);
            }

            spriteBatch.End();

            base.Draw(gameTime);
        }

        private void DrawRectangle(Rectangle r)
        {
            int bw = 1;
            Texture2D c = Textures.Black;
            Color c2 = Color.Black;
            if (!Collisions.RectanguloCubreUnSoloColor(r))
            {
                c = Textures.Red;
                c2 = Color.Red;
            }
            spriteBatch.Draw(c, new Rectangle(r.Left, r.Top, bw, r.Height), c2); // Left
            //spriteBatch.Draw(c, new Rectangle(r.Right, r.Top, bw, r.Height), c2); // Right
            spriteBatch.Draw(c, new Rectangle(r.Left, r.Top, r.Width, bw), c2); // Top
            //spriteBatch.Draw(c, new Rectangle(r.Left, r.Bottom, r.Width, bw), c2); // Bottom
        }

        private void DrawMovable(Movable m)
        {
            var ct = m.CurrentTexture();
            float layer = m.Position.Z > 0.9f ? 1f : 0.1f + m.Position.Z;
            spriteBatch.Draw(ct, new Vector2(m.Position.X, m.Position.Y), null, Color.White,
                             0.0f, new Vector2(0, 0), (1f + m.Position.Z), SpriteEffects.None, layer);
            /*spriteBatch.Draw(ct, new Vector2(m.Position.X, m.Position.Y), null, Color.White,
                             m.Direction, new Vector2(ct.Width/2, ct.Height/2), (1f + m.Position.Z), SpriteEffects.None, layer);*/
        }
    }
}
